<?php

namespace app\common\service;

use app\common\controller\Fypay;
use app\common\helper\FormatHelper;
use think\facade\Env;

/**
 * 富友支付相關
 */
class FuYouPayService
{

    private $config;
    private $pem;

    public function __construct()
    {
        $this->config = config('fu_you_config');
        $this->config['random_str'] = $this->createNoncestr();//随机字符串
        $this->pem = file_get_contents(Env::get('app_path') . 'common/library/keypem.pem');
    }


    /**
     * 条码支付
     * @param $order_type       订单类型，支付类型
     * @param $price            价格
     * @param $mchnt_order_no   商户商品编号
     * @param $auth_code        //扫码枪读取支付二维码
     * @return array
     */
    public function cspay($order_type,$price,$mchnt_order_no, $auth_code)
    {
        $Fypay = new Fypay();
        $order = [
            'order_type' => $order_type,
            'goods_des' => !empty($goods_des) ? $goods_des : '描述',
            'mchnt_order_no' => $mchnt_order_no,//商品编号
            'order_amt' => !empty($price) ? $price : 0.1,//总金额, 订单总金额，单位为分
            'term_ip' => get_client_ip(1),//服务器IP
            'txn_begin_ts' => date('YmdHis'),//交易起始时间, 订单生成时间
            'auth_code' => !empty($auth_code) ? $auth_code : '133558012434499905',//扫码枪读取支付二维码
        ];
        $res = $Fypay->ActivePay($order, $this->pem, $this->config);
        if ($res['result_code'] == '000000') {
            $res['create_ewm'] = create_ewm($res['qr_code'], config('upload_temp_path'), $order['mchnt_order_no'] . '.png');
            $res['mchnt_order_no'] = $order['mchnt_order_no'];
            return FormatHelper::fReturn('支付成功', $res, 200);
        } else {
            return FormatHelper::fReturn('支付失败', $res, 204);
        }

    }

    /**
     * 统一支付
     * @param $openid //用户open_id
     * @param $order_type //支付类型：支付宝：ALIPAY 微信：WECHAT
     * @param $goods_des //商品描述
     * @param $mchnt_order_no //商户订单号, 商户系统内部的订单号
     * @param $reserved_sub_appid //子商户公众号id
     * @param string $notify_url //支付成功回调地址
     */
    public function cs2pay($openid, $order_type, $goods_des, $mchnt_order_no, $reserved_sub_appid, $notify_url = '')
    {
        $Fypay = new Fypay();
        $order = [
            'order_type' => $order_type,
            'goods_des' => !empty($goods_des) ? $goods_des : '描述',
            'mchnt_order_no' => $mchnt_order_no,//商户订单号, 商户系统内部的订单号
            'order_amt' => 1,
            'term_ip' => get_client_ip(1),
            'txn_begin_ts' => date('YmdHis'),
            //'auth_code' => '130797265420571705',
            'openid' => $openid,
            'reserved_sub_appid' => !empty($reserved_sub_appid) ? $reserved_sub_appid : '',
            'notify_url' => url($notify_url, '', '', true),
        ];
        $res = $Fypay->PassivePay($order, $this->pem, $this->config);
        if ($res['result_code'] == '000000') {
            //$res['create_ewm'] = create_ewm($res['qr_code'], config('upload_temp_path'), $order['mchnt_order_no'] . '.png');
            $res['create_ewm'] = config('web_site_url').'/uploads/temp/'.create_ewm($res['qr_code'], config('upload_temp_path'), $order['mchnt_order_no'] . '.png');
            $res['mchnt_order_no'] = $order['mchnt_order_no'];
            return FormatHelper::fReturn('支付成功', $res, 200);
        } else {
            return FormatHelper::fReturn('支付失败', $res, 204);
        }
    }

    /**
     * 订单查询
     *
     * @param $order_type   订单类型，支付类型
     * @param $mchnt_order_no  商户商品订单编号
     * @return array
     */
    public function searchpay($order_type, $mchnt_order_no)
    {
        $Fypay = new Fypay();
        $order = [
            'order_type' => $order_type,
            'mchnt_order_no' => $mchnt_order_no,//订单号
        ];
        $res = $Fypay->OrderQuery($order, $this->pem, $this->config);
        //dump($res);//$res['trans_stat_msg']状态信息
        if ($res['result_code'] == '000000') {
            $res['create_ewm'] = create_ewm($res['qr_code'], config('upload_temp_path'), $order['mchnt_order_no'] . '.png');
            $res['mchnt_order_no'] = $order['mchnt_order_no'];
            return FormatHelper::fReturn('支付成功', $res, 200);
        } else {
            return FormatHelper::fReturn('支付失败', $res, 204);
        }
    }

    /**
     * 校验签名
     *
     * @param $param
     * @return bool
     */
    public function checkSign($param)
    {
        $Fypay = new Fypay();
        $xml = URLdecode($param['req']);
        $arr = $Fypay->toArray($xml);// 转成php数组
        if ($arr['result_code'] == '000000') {
            $data = [
                'curr_type' => $arr['curr_type'],
                'ins_cd' => $arr['ins_cd'],
                'mchnt_cd' => $arr['mchnt_cd'],
                'mchnt_order_no' => $arr['mchnt_order_no'],
                'order_amt' => $arr['order_amt'],
                'order_type' => $arr['order_type'],
                'random_str' => $arr['random_str'],
                'result_code' => $arr['result_code'],
                'result_msg' => $arr['result_msg'],
                'settle_order_amt' => $arr['settle_order_amt'],
                'term_id' => $arr['term_id'],
                'transaction_id' => $arr['transaction_id'],
                'txn_fin_ts' => $arr['txn_fin_ts'],
                'user_id' => $arr['user_id'],
            ];
            //进行签名验证
            $sign = $Fypay->make_sign($data);
            if ($sign == $arr['sign']) {
                return true;
            } else {
                dump($sign); return false;
            }
        } else {
            dump('回调错误'); return false;
        }
    }

    //主扫统一下单回调
    public function notify()
    {
        $param = $this->request->param();
        $Fypay = new Fypay();
        $xml = URLdecode($param['req']);
        // 转成php数组
        $arr = $Fypay->toArray($xml);
        //file_put_contents('xml.txt',json_encode($arr));
        //验证签名
        if ($arr['result_code'] == '000000') {
            $data = [
                'curr_type' => $arr['curr_type'],
                'ins_cd' => $arr['ins_cd'],
                'mchnt_cd' => $arr['mchnt_cd'],
                'mchnt_order_no' => $arr['mchnt_order_no'],
                'order_amt' => $arr['order_amt'],
                'order_type' => $arr['order_type'],
                'random_str' => $arr['random_str'],
                'result_code' => $arr['result_code'],
                'result_msg' => $arr['result_msg'],
                'settle_order_amt' => $arr['settle_order_amt'],
                'term_id' => $arr['term_id'],
                'transaction_id' => $arr['transaction_id'],
                'txn_fin_ts' => $arr['txn_fin_ts'],
                'user_id' => $arr['user_id'],
            ];
            //进行签名验证
            $sign = $Fypay->make_sign($data);
            if ($sign == $arr['sign']) {
                //进行订单操作
                dump($arr); return true;
            } else {
                dump($arr); return false;
            }
        } else {
            echo "回调失败"; return false;
        }
    }

    //订单退款
    public function refund()
    {
        $Fypay = new Fypay();
        $order = [
            'order_type' => 'ALIPAY',
            'mchnt_order_no' => 'D413297888384921',//平台的订单号
            'refund_order_no' => $this->create_ordersn(),//商户退款单号
            'total_amt' => 2,//总金额
            'refund_amt' => 2,//退款金额
            'operator_id' => 'zhangsan',//操作员
        ];
        $res = $Fypay->OrderRefund($order, $this->pem, $this->config);
        return FormatHelper::fReturn('支付成功', $res, 200);
    }

    //退款查询
    public function searchrefund()
    {
        $Fypay = new Fypay();
        $order = [
            'refund_order_no' => 'D413323575870098',//退款订单号
        ];
        $res = $Fypay->RefundQuery($order, $this->pem, $this->config);

        return FormatHelper::fReturn('支付成功', $res, 200);
    }

    //作用：产生随机字符串，不长于32位
    private function createNoncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    //生成订单号
    private function create_ordersn()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N');
        $orderSn = $yCode[intval(date('Y')) - 2019] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
        return $orderSn;
    }
}